package com.beijing.cyou.service.impl;

import java.util.Date;
import java.util.Set;

import com.beijing.cyou.model.*;
import com.beijing.cyou.module.PopedomData;
import com.beijing.cyou.module.PopedomResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.beijing.cyou.mapper.UserMapper;
import com.beijing.cyou.params.UserParams;
import com.beijing.cyou.redis.UserRedisService;
import com.beijing.cyou.service.UserService;
import com.beijing.cyou.utils.CommonConstant;
import com.beijing.cyou.utils.NotNullHelps;
import com.beijing.cyou.utils.UserHelpConstant;
import com.beijing.cyou.utils.UserRedisKey;
import org.springframework.web.client.RestTemplate;
import springfox.documentation.spring.web.json.Json;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserRedisService userRedisService ;

	@Autowired
	private RestTemplate restTemplate ;
	
	@Autowired
	private UserMapper userMapper;
	
	private boolean updateFlag ;

	private Integer sqlResult ;
	
	private String redisKey;
	
	private String message;

	@Override
	public UserInfo getUserInfoById(Long userId) {
		return userMapper.getUserInfoById(userId);
	}
	
	@Override
	public Long getUserIdByUserEmail(String userEmail) {
		return userMapper.userExist(userEmail);
	}
	
	@Override
	public UserOnline getRedisUser(String token)throws Exception {
		UserOnline userOnline = null ;
		Integer base = UserHelpConstant.USER_TOKEN_POOL ;
		if (NotNullHelps.checkNotNull(token) == false) {
			message = CommonConstant.common_message_exception;
		}else {
			userRedisService.chooseRedisPool(base);
			redisKey = this.userTokenFormat(token);
			String value = userRedisService.getRedisStringValue(redisKey);
			userOnline = JSON.parseObject(value, UserOnline.class);
			if (NotNullHelps.isNotNull(userOnline) == false) {
				message = "$$ 读取用户信息异常！ @@";
			}else {
				message = "$$ 成功--用户信息读取完毕！ @@";
			}		
		}
		log.info(message);
		return userOnline;
	}
	
	@Override
	public User selectUser(UserParams condition) throws Exception{
		User user = null ;
		String token = condition.getToken();
		Long userId = condition.getUserId();
		Integer dbNum = UserHelpConstant.USER_TOKEN_POOL ;
		if (NotNullHelps.checkNotNull(userId) == false) {
			message = CommonConstant.common_message_exception;
		}else {
			if (NotNullHelps.isNotNull(token) == false) {
				user = userMapper.selectUserByUserId(userId);
				message = "$$ 其他用户查询~~~用户信息 @@" ;
			}else {
				userRedisService.chooseRedisPool(dbNum);
				redisKey = this.userTokenFormat(token);
				String value = userRedisService.getRedisStringValue(redisKey);
				UserOnline userOnline = JSON.parseObject(value, UserOnline.class);
				if (NotNullHelps.isNotNull(userOnline) == true) {
					Long userID = userOnline.getUserId();
					if (userId.equals(userID) == false) {
						System.out.println("## redis-token信息不符 @@");
					}
					user = userMapper.selectUserByUserId(userId);
					message = NotNullHelps.isNotNull(user) ? "#用户信息查询成功@":"@异常-用户查询#";
				}
			}
		}
		log.info(message);
		return user ;
	}
	
	@Override
	public UserInfo retriveUserInfo(UserParams condition) throws Exception{
		UserInfo userInfo = null ;
		String domain = condition.getDomain();
		String userName = condition.getUserName();
		String userEmail = condition.getUserEmail();
		String userGender = condition.getUsergender();
		String userComment = condition.getUsercomment();
		if (NotNullHelps.checkNotNull(domain, userName, userEmail, userGender, userComment) == false) {
			message = CommonConstant.common_message_exception;
		} else {
			String userPrefix = userEmail.split("@")[0];
			if (userPrefix.equalsIgnoreCase(userName) == false) {
				message = "## 用户信息前后不符 @@" ;
			}else {
				String token = condition.getToken() ;
				Long userId = findOutUserId(condition, userEmail, userPrefix);
				condition.setUserId(userId);
				boolean creamFlag = this.makeSureCreamFlag(condition);
				if (NotNullHelps.checkNotNull(token)) { 
					UserOnline userOnline = condition.changToUserOnline();
					userOnline.setCreamFlag(creamFlag);
					this.markupRedisUser(userOnline);
				}
				if (NotNullHelps.isNotNull(userId)) {
					userInfo = userMapper.getUserInfoById(userId);
					message = "%% 用户数据索引成功 @@";
					userInfo.setCreamFlag(creamFlag);
					userInfo.setUserToken(token);
				}
				this.updateUserToken(condition);
			}
		}
		log.info(message);
		return userInfo;
	}

	protected Long findOutUserId(UserParams condition, String userEmail, String userPrefix) throws Exception {
		Long userId = userMapper.userExist(userEmail);
		if (NotNullHelps.isNotNull(userId) == false) {
			log.info("%% 邮箱不符合，复查邮箱前缀！！ @@ mailPrefix : " + userPrefix );
			userId = userMapper.userMailPrefixExist(userPrefix);
			if (NotNullHelps.isNotNull(userId) == false) {
				UserOnline userOnline = condition.changToUserOnline();
				this.registRedisUser(userOnline);
				UserVO userVO = condition.changToUserVO();
				this.setUserDefault(userVO);
				sqlResult = userMapper.insertUser(userVO);
				if (NotNullHelps.isNotNull(sqlResult) == false) {
					message = "$$ 用户数据异常插入 ##" ;
				}else {
					userId = userVO.getUserId();
					condition.setUserId(userId);
					this.markupUserRelation(condition);
					log.info("%% 成功！用户数据保存成功 @@");
				}
			}

		}
		return userId;
	}

	@Override
	public void markupUserRelation(UserParams condition) {
		Long userId = condition.getUserId();
		if (NotNullHelps.isNotNull(userId)) {
			UserOrgz userOrgz = new UserOrgz(userId, UserHelpConstant.USER_ORGZID, UserHelpConstant.USER_LEVEL);
			userOrgz.setCreateDate(new Date());
			userOrgz.setFlag(new Date());
			sqlResult = userMapper.insertUserOrgz(userOrgz);
			UserInRole userInRole = new UserInRole(userId, UserHelpConstant.ROLE_KNOWID);
			userInRole.setCreateDate(new Date());
			userInRole.setFlag(new Date());
			sqlResult = userMapper.insertUserInRole(userInRole);
			userInRole.setRoleId(UserHelpConstant.ROLE_PLAYID);
			sqlResult = userMapper.insertUserInRole(userInRole);
		}
	}
	
	private String userTokenFormat(String token) {
		return String.format(UserRedisKey.USER_TOKEN, token);
	}
	
	private String userRegistFormat() {
		return String.format(UserRedisKey.USER_REGIST);
	}
	
	@Override
	public void markupRedisUser(UserOnline userOnline)throws Exception {
		Integer dataBaseNumber = UserHelpConstant.USER_TOKEN_POOL ;
		if (NotNullHelps.propertyAllNotNull(userOnline) == false) {
			System.out.println("&& 用户属性不充实！ $$");
		}else {
			String token = userOnline.getToken();
			String redisKey = this.userTokenFormat(token);
			String userValue = JSON.toJSONString(userOnline);
			userRedisService.chooseRedisPool(dataBaseNumber);
			userRedisService.setRedisStringValue(redisKey, userValue);
		}
	}
	
	@Override
	public void registRedisUser(UserOnline userOnline)throws Exception {
		log.info("&& 需要注册的用户--备份留存！  @@");
		System.out.println();
		Integer dataBaseNumber = UserHelpConstant.USER_TOKEN_POOL ;
		String redisKey = this.userRegistFormat();
		String userValue = JSON.toJSONString(userOnline);
		userRedisService.chooseRedisPool(dataBaseNumber);
		userRedisService.insertToSet(redisKey, userValue);
		log.info("**** 注册用户--结束 ！  ))))) + userName : " + userOnline.getUserName());
	}
	
	protected void setUserDefault(UserVO userVO) {
		if (NotNullHelps.isNotNull(userVO)) {
			userVO.setUserPosition(UserHelpConstant.user_position);
			userVO.setUserPassword(UserHelpConstant.user_password);
			userVO.setUserAddress(UserHelpConstant.user_address);
			userVO.setUserStatus(UserHelpConstant.USER_STATUS);
			userVO.setUserDeptId(UserHelpConstant.USER_DEPTID);
			userVO.setUserCreateDate(new Date());
			userVO.setPasswordDate(new Date());
			userVO.setFlag(new Date());
		}
	}

	protected void updateTokenCreamFlag(String userToken) throws Exception {
		userRedisService.chooseRedisPool(UserHelpConstant.USER_TOKEN_POOL);
		boolean existFlag = userRedisService.redisKeyExist(userToken);
		if (existFlag == false) {
			message = "^^ redisKey 数据已不存在 @@" ;
		} else {
			String userStringData = userRedisService.getRedisStringValue(userToken);
			UserOnline userData = JSON.parseObject(userStringData, UserOnline.class);
			UserParams condition = new UserParams(userData.getUserId());
			boolean creamFlag = this.makeSureCreamFlag(condition);
			userData.setCreamFlag(creamFlag);
			String stringValue = JSON.toJSONString(userData);
			userRedisService.setRedisStringValue(userToken, stringValue);
			message = "** creamFlag 数据更新完毕 @@ + token : " + userToken;
		}
		log.info(message);
	}



	@Override
	public void makeSureUsedTokenCreamFlag()throws Exception {
		Set<String> tokenSet = userRedisService.listUsedUserTokenKeys();
		if (NotNullHelps.isNotNull(tokenSet)) {
			for (String token : tokenSet) {
				String userToken = this.userTokenFormat(token);
				this.updateTokenCreamFlag(userToken);
			}
		}
	}


	@Override
	public void makeSureAllTokenCreamFlag() throws Exception{
		Set<String> tokenKeySet = userRedisService.listAllUserTokenKeys();
		if (NotNullHelps.isNotNull(tokenKeySet)) {
			log.info(" number : " + tokenKeySet.size());
			for (String userToken : tokenKeySet) {
				this.updateTokenCreamFlag(userToken);
			}
		}
	}

	@Override
	public void updateUsedMysqlUserToken()throws Exception {
		Set<String> tokenSet = userRedisService.listUsedUserTokenKeys();
		if (NotNullHelps.isNotNull(tokenSet)) {
			log.info("%% size : " + tokenSet.size());
			for (String token : tokenSet) {
				UserParams condition = new UserParams(token);
				this.updateUserToken(condition);
			}
		}
	}

	@Override
	public boolean updateUserInfo(UserParams condition) {
		updateFlag = false ;
		Long userId = condition.getUserId() ;
		if (NotNullHelps.isNotNull(userId) == false) {
			message = "^^ userId 主键缺失! @@" ;
		}else {
			UserVO userVO = new UserVO(userId);
			String phone = condition.getPhone();
			String mobile = condition.getMobile();
			boolean gender = condition.isGender();
			String address = condition.getAddress();
			Integer userGender = (gender == false) ? 0 : 1 ;
			userVO.setUserGender(userGender);
			userVO.setUserAddress(address);
			userVO.setUserMobile(mobile);
			userVO.setUserPhone(phone);
			sqlResult = userMapper.updateUserNormalInfo(userVO);
			if (NotNullHelps.isNotNull(sqlResult) == false) {
				message = "%% 前后无变化，无须更新 @@" ;
			}else {
				message = "$$ 更新成功！ @@" ;
				updateFlag = true ;
			}
		}
		log.info(message);
		return updateFlag ;
	}

	@Override
	public boolean updateUserToken(UserParams condition)throws Exception {
		updateFlag = false ;
		String token = condition.getToken();
		if (NotNullHelps.isNotNull(token) == false) {
			message = UserHelpConstant.exception_message;
		} else {
			String userToken = this.userTokenFormat(token);
			userRedisService.chooseRedisPool(UserHelpConstant.USER_TOKEN_POOL);
			boolean existFlag = userRedisService.redisKeyExist(userToken);
			if (existFlag == false) {
				message = "% redisKey 数据已经不存在了 @";
			} else {
				String userStringData = userRedisService.getRedisStringValue(userToken);
				UserOnline userData = JSON.parseObject(userStringData, UserOnline.class);
				UserToken tokenUser = userData.changeToUserToken();
				tokenUser.setTokenInfo(userStringData);
				tokenUser.setTokenDate(new Date());
				tokenUser.setUserToken(token);
				Long existId = userMapper.userTokenExist(tokenUser);
				if (NotNullHelps.isNotNull(existId) == true) {
					message = "%% user-token 已存在 @@";
					updateFlag = true;
				} else {
					sqlResult = userMapper.insertUserToken(tokenUser);
					if (NotNullHelps.isNotNull(sqlResult) == false) {
						message = "$$ 保存异常 @@ ";
					} else {
						message = "@@ 成功保存 $$";
						updateFlag = true;
					}
					message += " # userName = " + tokenUser.getUserName();
				}
			}
		}
		log.info(message);
		return updateFlag;
	}

	@Override
	public boolean makeSureCreamFlag(UserParams condition) {
		boolean flag = false ;
		Long userId = condition.getUserId();
		if (NotNullHelps.checkNotNull(userId) == false) {
			message = UserHelpConstant.exception_message;
		} else {
			StringBuffer popedomPath = new StringBuffer(UserHelpConstant.km_server_path);
			Long popedomId = UserHelpConstant.POPEDOM_CREAM_ID;
			popedomPath.append(UserHelpConstant.popedom_path);
			popedomPath.append("?debug=km");
			popedomPath.append("&userId=" + userId);
			popedomPath.append("&popedomId=" + popedomId);
			PopedomResult result = restTemplate.getForObject(popedomPath.toString(), PopedomResult.class);
			if (NotNullHelps.isNotNull(result) && UserHelpConstant.RESULT_SUCCESS.equals(result.getCode())) {
				PopedomData popedomData = result.getData();
				String userName = popedomData.getUserName();
				Integer popedomType = popedomData.getPopedomType();
				if (UserHelpConstant.POPEDOM_TYPE_YES.equals(popedomType)) {
					message = "%% 拥有高潜权限 @@ + [" + userName + "]";
					flag = true;
				} else if (UserHelpConstant.POPEDOM_TYPE_NO.equals(popedomType)) {
					message = "@ 没有高潜权限 #" ;
				}
			} else {
				message = "@@ 接口异常 ## userId = " + userId ;
			}
		}
		log.info(message);
		return flag ;
	}
	

}
